//---------------------------------------------------------------------
//  This file is part of the Background Motion solution.
// 
//  Copyright (C) Mindscape (TM).  All rights reserved.
//  http://www.mindscape.co.nz
// 
//  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System.Data.DLinq;

using Microsoft.Practices.EnterpriseLibrary.Validation;

namespace Mindscape.BackgroundMotion.Model
{
  /// <summary>
  /// Represents the association between a <see ref="Contribution"/> and a <see ref="Tag"/>
  /// </summary>
  [Table(Name = "ContributionTag")]
  public sealed class ContributionTag : ModelObject
  {
    private int _id;
    private int _contributionId;
    private int _tagId;

    private EntityRef<Contribution> _contribution;
    private EntityRef<Tag> _tag;

    public ContributionTag()
    {
      _contribution = default(EntityRef<Contribution>);
      _tag = default(EntityRef<Tag>);
    }

    [Column(Storage = "_id", Id = true, AutoGen = true)]
    public override int Id
    {
      get { return _id; }
      set
      {
        if (_id != value)
        {
          OnPropertyChanging("Id");
          _id = value;
          OnPropertyChanged("Id");
        }
      }
    }

    [Column(Storage = "_contributionId")]
    public int ContributionId
    {
      get { return _contributionId; }
      set
      {
        if ((_contributionId != value))
        {
          OnPropertyChanging("ContributionId");
          _contributionId = value;
          OnPropertyChanged("ContributionId");
        }
      }
    }

    [Column(Storage = "_tagId")]
    public int TagId
    {
      get { return _tagId; }
      set
      {
        if ((_tagId != value))
        {
          OnPropertyChanging("TagId");
          _tagId = value;
          OnPropertyChanged("TagId");
        }
      }
    }

    [Association(Storage = "_contribution", ThisKey = "ContributionId", IsParent = true)]
    public Contribution Contribution
    {
      get { return _contribution.Entity; }
      set
      {
        UpdateAssociation("Contribution", ref _contribution, value,
          (Contribution c) => c.ContributionTags.Remove(this),
          (Contribution c) => c.ContributionTags.Add(this));
      }
    }

    [Association(Storage = "_tag", ThisKey = "TagId", IsParent = true)]
    public Tag Tag
    {
      get { return _tag.Entity; }
      set
      {
        UpdateAssociation("Tag", ref _tag, value,
          (Tag t) => t.ContributionTags.Remove(this),
          (Tag t) => t.ContributionTags.Add(this));
      }
    }

    /// <summary>
    /// Validates this instance for a correct state
    /// </summary>
    /// <remarks>
    /// This is called by the Enterprise Library Validation framework
    /// </remarks>
    /// <param name="results">A set of ValidationResults indicating validation issues with the current instance</param>
    protected override void Validate(ValidationResults results)
    {
      results.AddAllResults(Validation.ValidateFromAttributes(this));

      Require("Tag", TagId, Tag, results);
      Require("Contribution", ContributionId, Contribution, results);
    }
  }
}